package juc.atomic;

import java.util.concurrent.atomic.AtomicReferenceArray;

class UpdateTask implements Runnable {
    private AtomicReferenceArray<String> atomicArray;
    private int index;
    private String oldValue;
    private String newValue;

    public UpdateTask(AtomicReferenceArray<String> atomicArray, int index, String oldValue,String newValue) {
        this.atomicArray = atomicArray;
        this.index = index;
        this.oldValue = oldValue;
        this.newValue = newValue;
    }

    @Override
    public void run() {
        while (true) {
            //这是一个原子操作，用于比较atomicArray数组在index位置的值是否等于currentValue，如果相等，则将其更新为newValue。
            //例如，两个线程刚进来都是获取到"initialValue"，然后都更新为"value1"，但是只有一个线程的更新成功，另一个线程的更新失败，
            if (atomicArray.compareAndSet(index, oldValue, newValue)) {
                System.out.println(Thread.currentThread().getName() + " 更新成功，新值: " + newValue);
                break;
            }
        }
    }
}

public class AtomicReferenceArrayMultiThreadExample {
    public static void main(String[] args) {
        AtomicReferenceArray<String> atomicArray = new AtomicReferenceArray<>(5);
        atomicArray.set(0, "initialValue");

        Thread thread1 = new Thread(new UpdateTask(atomicArray, 0, "initialValue","value1"), "Thread-1");
        Thread thread2 = new Thread(new UpdateTask(atomicArray, 0, "value1","value2"), "Thread-2");

        thread1.start();
        thread2.start();

        try {

            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("最终值: " + atomicArray.get(0));
        /**
         *  输出结果：
         *  Thread-2 更新成功，新值: value2
         *  Thread-1 更新成功，新值: value1
         *  最终值: value2
         *  问题：为什么结果正确而打印顺序不对？
         *  解析：因为在整个并发过程中，只有atomicArray.compareAndSet(index, oldValue, newValue)是原子操作，所以两个线程的打印顺序是不确定的。
         * 例如：当线程二执行到compareAndSet方法时，线程一已经更新了数组的值，但是还没有继续执行，此时线程二开始执行compareAndSet方法返回true，并打印成功，在此时，再切换回线程一的循环继续执行，
           所以打印就不一致了。
         */
    }
}
